﻿/**************************************************
 * Quantum Quest Game Project                     *
 *                                                *
 * Version:                                       *
 * Design 1.0                                     *
 *                                                *
 * Authors:                                       *
 * Michael Fowler                                 *
 * Michael Timmins                                *
 * Octavian Geagla                                *
 * Eric Cooper                                    *
 *                                                *
 * License:                                       *
 * Unknown                                        *
 *                                                *
 * ************************************************/

/**************************************************
 * QQPhysics.cs                                   *
 *                                                *
 * Created:                                       *
 * 6/16/09, Octavian Geagla                       *
 *                                                *
 * Updated:                                       *
 * 6/16/09                                        *
 *                                                *
 * Description:                                   *
 * This is what will handle gravity, collisions,  *
 * and other things we might need.                *
 *                                                *
 * ************************************************/

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;


namespace QuantumQuest
{
    public class QQPhysics
    {        

        public const double G = 6.67e-11;       
       
        public QQPhysics()
        {
            
        }

        //the next two functions change NOTHING but the position; take accel to be constant regardless of IsConstantAccel;
        //maybe I should add a third to 
        public QQBody UpdatePosition(QQBody body, double dt)
        {
            if (body.IsStationary)
            {
                body.Velocity = new QQVector2(0.0,0.0);
                body.Acceleration= new QQVector2(0.0,0.0);
                return body;
            }         

            QQBody tempBody = body;
            tempBody.Velocity += tempBody.Acceleration * dt;
            tempBody.Position += tempBody.Velocity * dt + (0.5) * (tempBody.Acceleration) * (Math.Pow(dt, 2));
            return tempBody;

        }
        public QQBody UpdatePosition(QQList bodyList, int index, double dt)
        {
            QQBody tempBody = (QQBody)bodyList[index];
            if (tempBody.IsStationary)
            {
                tempBody.Velocity = new QQVector2(0.0, 0.0);
                tempBody.Acceleration = new QQVector2(0.0, 0.0);
                return tempBody;
            }            
            tempBody.Velocity += tempBody.Acceleration * dt;
            tempBody.Position += tempBody.Velocity * dt + (0.5) * (tempBody.Acceleration) * (Math.Pow(dt, 2));
            return tempBody;
        }
       

        public QQList ApplyGravity(QQList bodyList, double dt)
        {

            //todo
            QQList newList = bodyList;
            QQVector2 dir = new QQVector2(0,0);
            
            for (int i = 0; i < bodyList.Count; i++)
            {
                if (((QQBody)newList[i]).IsConstantAccel)
                {
                    continue;
                }
                if (!((QQBody)newList[i]).IsStationary)
                {
                    //HERE
                }
                else
                {
                    ((QQBody)newList[i]).Acceleration = new QQVector2(0.0, 0.0);
                    ((QQBody)newList[i]).Velocity = new QQVector2(0.0, 0.0);
                }
            }


            return newList;

        }
        public QQBody ApplyGravity(QQList bodyList, QQBody body, double dt)
        {
            
            int index = bodyList.IndexOf(body);
            return ApplyGravity(bodyList, index, dt);
        }


        public QQBody ApplyGravity(QQList bodyList, int index, double dt)
        {
            QQBody tempBody = (QQBody)bodyList[index];
            QQVector2 dir = new QQVector2(0, 0);
            QQVector2 dirMag = new QQVector2(0, 0);
            QQVector2 dist = new QQVector2(0, 0);
            tempBody.Acceleration = new QQVector2(0, 0);

            if (tempBody.IsConstantAccel)
            {
                tempBody.Velocity += tempBody.Acceleration * dt;
                tempBody.Position += tempBody.Velocity * dt + (0.5) * (tempBody.Acceleration) * (Math.Pow(dt, 2));
                return tempBody;
            }
            if (!((QQBody)bodyList[index]).IsStationary)
            {
                for (int i = 0; i < bodyList.Count; i++)
                {
                    if (i != index)
                    {
                        dir = tempBody.Position - ((QQBody)(bodyList[i])).Position;
                        dist = dir;
                        dir.Normalize();
                        dirMag = dir;
                        dirMag.Magnitude = (G * (tempBody.Mass * ((QQBody)(bodyList[i])).Mass)) / (Math.Pow(dist.Magnitude, 2));
                        tempBody.Acceleration += dirMag;
                    }
                }
                tempBody.Velocity += tempBody.Acceleration * dt;
                tempBody.Position += tempBody.Velocity * dt + (0.5) * (tempBody.Acceleration) * (Math.Pow(dt, 2));
            }
            else
            {
                tempBody.Acceleration = new QQVector2(0.0, 0.0);
                tempBody.Velocity = new QQVector2(0.0, 0.0);
            }
            return tempBody;
        }
        
        //this should do the trick, though it could be slow?  i am thinking the most that the covering rectangle intersection is 100-200 points?  which is not bad
        public bool AreInContact(QQBody s1, QQBody s2)
        {
            Rect r1 = new Rect(Canvas.GetLeft(s1),Canvas.GetTop(s1), s1.Width, s1.Height);
            Rect r2 = new Rect(Canvas.GetLeft(s2), Canvas.GetTop(s2), s2.Width,s2.Height);
            // Bounding box collision
            r1.Intersect(r2);
            if (r1.IsEmpty)
            {
                return false;
            }
            Point pt = new Point();
            int l = (int)r1.Left;
            int r = (int)r1.Right;
            int t = (int)r1.Top;
            int b = (int)r1.Bottom;
            // Now perform a pixel
            // perfection collision detection
            // by hit testing every point
            //	within the overlapping Rect
            for (int x = l; x <= r; x++)
            {
                for (int y = t; y <= b; y++)
                {
                    pt.X = x;
                    pt.Y = y;
                    List<UIElement> hits1 = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(pt, s1) as List<UIElement>;
                    List<UIElement> hits2 = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(pt, s2) as List<UIElement>;
                    
                    if((hits1.Count!=0)&&(hits2.Count!=0))
                    {
                        return true;
                    }
                }
            }
            return false;
        }






    }
}
